package com.dyna.demo.excel.service.impl;

import cn.hutool.core.collection.ListUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.dyna.core.exception.CustomException;
import com.dyna.cp.mybatis.domain.dto.ZsdPlanExcelDto;
import com.dyna.cp.mybatis.mapper.ZsdPlanMapper;
import com.dyna.demo.excel.domain.dto.Student;
import com.dyna.demo.excel.domain.dto.Teacher;
import com.dyna.demo.excel.service.ExcelService;
import com.dyna.excel.core.util.ExcelUtil;
import com.dyna.utils.RdsUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class ExcelServiceImpl implements ExcelService {

    @Value("${dyna.file.path}")
    private String filePath;

    @Resource
    private ZsdPlanMapper zsdPlanMapper;

    /**
     * 初始化数据
     */
    private static List<Student> initData() {
        Student student1 = new Student("张三", 18, "男", "北京市朝阳区", "本科1", "1年");
        Student student2 = new Student("张三", 18, "男", "北京市朝阳区", "本科1", "1年");
        Student student3 = new Student("李四", 20, "女", "上海市浦东新区", "本科2", "2年");
        Student student4 = new Student("李四", 20, "女", "上海市浦东新区", "博士1", "3年");
        Student student5 = new Student("李四", 20, "女", "上海市浦东新区", "博士2", "4年");
        Student student6 = new Student("李四", 20, "女", "上海市浦东新区", "博士3", "5年");
        return new ArrayList<>(ListUtil.of(student1, student2, student3, student4, student5, student6));
    }

    public void exportByTemplate(String result) {
        RdsUtil.set("test",result);
        List<Student> students = initData();
        Teacher teacher = new Teacher("啊啊啊",  "教授");
/*
        ExcelUtil.getWriter("template/测试写入excel数据1.xlsx")
                .write(students, true)
                .flush(new File("E:\\data\\exportFile\\糊涂工具导出" + System.currentTimeMillis() + ".xlsx"));
*/

//        String templateFileName = "E:\\Project\\dyna-cloud\\dyna-cloud-service\\dyna-cloud-service-demo\\dyna-cloud-service-demo-biz\\src\\main\\resources\\template\\测试写入excel数据1.xlsx";
        // 方案一
/*        String exportFilePath = "E:\\data\\exportFile\\阿里巴巴EasyExcel" + System.currentTimeMillis() + ".xlsx";
        EasyExcel.write(exportFilePath)
                .withTemplate(FileUtil.file("template/测试写入excel数据1.xlsx"))
                .sheet()
                .doFill(students);*/

        // 方案二
        String exportFilePath = "E:\\data\\exportFile\\阿里巴巴EasyExcel" + System.currentTimeMillis() + ".xlsx";
        ExcelWriter excelWriter = null;
        try {
/*            File file = new File("src/main/resources/template/测试写入excel数据2.xlsx");
            InputStream inputStream = new FileInputStream(file);*/

            InputStream inputStream = getClass().getClassLoader().getResourceAsStream("ClassPath:template/测试写入excel数据2.xlsx");

            excelWriter = EasyExcel.write(exportFilePath)
                    .withTemplate(inputStream)
                    .build();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new CustomException(e.getMessage());
        }
        WriteSheet writeSheet = EasyExcel.writerSheet().build();
        assert excelWriter != null;
        excelWriter.fill(students, writeSheet);
//        Map<String, Object> map = new HashMap<>(16);
//        map.put("edu", teacher.getEdu());
//        map.put("experience", teacher.getExperience());
//        excelWriter.fill(map, writeSheet);
        System.out.println("导出成功");
    }

    @Override
    public void exportByStream(HttpServletResponse response) {
        List<Student> students = initData();
        // 导出文件的名称
        String fileName = ExcelUtil.getRandomFileName("测试导出");
        // 设置响应头
        ExcelUtil.setResponseInfo(response, fileName);
        try {
            HorizontalCellStyleStrategy horizontalCellStyleStrategy = getHorizontalCellStyleStrategy();
            EasyExcel.write(response.getOutputStream(), Student.class)
                    // 指定sheet的名称
                    .sheet("学生信息")
                    .registerWriteHandler(horizontalCellStyleStrategy)
                    // 写入数据
                    .doWrite(students);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw new CustomException("导出失败");
        }
    }

    @NotNull
    private static HorizontalCellStyleStrategy getHorizontalCellStyleStrategy() {
        // 创建样式策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 12);
        headWriteCellStyle.setWriteFont(headWriteFont);

        // 设置表头的水平和垂直居中
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        // 内容单元格样式
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER_SELECTION); // 水平居中
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中

        // 创建水平样式策略
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    }

    @Override
    public List<Student> readExcel(MultipartFile file) {
        final List<Student> list = new ArrayList<Student>();

        try {
            EasyExcel.read(file.getInputStream(), Student.class, new AnalysisEventListener<Student>(){
                @Override
                public void invoke(Student student, AnalysisContext analysisContext) {
                    log.info("解析到一条数据:{}", JSON.toJSONString(student));
                    list.add(student);
                }
                @Override
                public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                    log.info("所有数据解析完成！");
                }
            }).sheet().doRead();
        } catch (Exception e) {
            throw new CustomException("解析excel异常，请检查excel数据");
        }
        return list;
    }

    @Override
    public void merge(HttpServletResponse response) {
        String fileName = ExcelUtil.getRandomFileName("合并单元格");
        ExcelUtil.setResponseInfo(response, fileName);
        List<ZsdPlanExcelDto> dataList = zsdPlanMapper.selectAll();
        try {
            exportDataWithMerge(response, dataList);
        } catch (Exception e) {
            throw new CustomException(e.getMessage());
        }
        log.info("导出文件成功");
    }

    private void exportDataWithMerge(HttpServletResponse response, List<ZsdPlanExcelDto> dataList) {
        try {
/*            String filename = filePath + ExcelUtil.getPathFileName("计划信息");
            FileUtil.createFile(filename);*/
            String filename = ExcelUtil.getRandomFileName("计划信息");
            log.info("正在导出文件:{}", filename);
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), ZsdPlanExcelDto.class).build();
            WriteSheet writeSheet4 = EasyExcel.writerSheet(0, "合并单元格").build();
            int[] ints = {0, 1, 2, 3, 4, 5};
//            writeSheet4.setCustomWriteHandlerList(Collections.singletonList(new ExcelMergeHandler(2, ints)));
            excelWriter.write(dataList, writeSheet4);
            excelWriter.finish();
        }catch (Exception e) {
            throw new CustomException(e.getMessage());
        }

    }


}
